package com.zenithmind.library.controller.base;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 图书馆控制器基类
 * 遵循单一职责原则：只负责HTTP请求处理的通用逻辑
 * 遵循里氏替换原则：子类可以替换父类而不影响程序的正确性
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
public abstract class BaseLibraryController {

    /**
     * 处理验证错误
     * 
     * @param bindingResult 绑定结果
     * @return 错误结果
     */
    protected Result<Void> handleValidationErrors(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<String> errors = bindingResult.getFieldErrors()
                    .stream()
                    .map(FieldError::getDefaultMessage)
                    .collect(Collectors.toList());
            String errorMessage = String.join(", ", errors);
            log.warn("参数验证失败：{}", errorMessage);
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), errorMessage, null);
        }
        return Result.success();
    }

    /**
     * 处理业务异常
     * 
     * @param e 异常
     * @param operation 操作名称
     * @return 错误结果
     */
    protected <T> Result<T> handleBusinessException(Exception e, String operation) {
        log.error("{}操作失败", operation, e);
        return Result.fail(ResultCode.FAIL.getCode(), operation + "失败：" + e.getMessage(), null);
    }

    /**
     * 构建成功的分页结果
     * 
     * @param pageResult 分页结果
     * @param <T> 数据类型
     * @return 成功结果
     */
    protected <T> Result<PageResult<T>> buildPageResult(PageResult<T> pageResult) {
        return Result.success(pageResult);
    }

    /**
     * 构建成功的列表结果
     * 
     * @param list 列表数据
     * @param <T> 数据类型
     * @return 成功结果
     */
    protected <T> Result<List<T>> buildListResult(List<T> list) {
        return Result.success(list);
    }

    /**
     * 构建成功的单个对象结果
     * 
     * @param data 数据对象
     * @param <T> 数据类型
     * @return 成功结果
     */
    protected <T> Result<T> buildSuccessResult(T data) {
        return Result.success(data);
    }

    /**
     * 构建成功的无数据结果
     * 
     * @return 成功结果
     */
    protected Result<Void> buildSuccessResult() {
        return Result.success();
    }

    /**
     * 构建失败结果
     * 
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 失败结果
     */
    protected <T> Result<T> buildFailResult(String message) {
        return Result.fail(ResultCode.FAIL.getCode(), message, null);
    }

    /**
     * 构建参数错误结果
     * 
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 参数错误结果
     */
    protected <T> Result<T> buildParamErrorResult(String message) {
        return Result.fail(ResultCode.PARAM_ERROR.getCode(), message, null);
    }

    /**
     * 构建未找到结果
     * 
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 未找到结果
     */
    protected <T> Result<T> buildNotFoundResult(String message) {
        return Result.fail(ResultCode.NOT_FOUND.getCode(), message, null);
    }

    /**
     * 验证ID参数
     * 
     * @param id ID参数
     * @param paramName 参数名称
     * @return 验证结果
     */
    protected Result<Void> validateId(String id, String paramName) {
        if (id == null || id.trim().isEmpty()) {
            return buildParamErrorResult(paramName + "不能为空");
        }
        return Result.success();
    }

    /**
     * 验证ID列表参数
     * 
     * @param ids ID列表
     * @param paramName 参数名称
     * @return 验证结果
     */
    protected Result<Void> validateIds(List<String> ids, String paramName) {
        if (ids == null || ids.isEmpty()) {
            return buildParamErrorResult(paramName + "不能为空");
        }
        for (String id : ids) {
            if (id == null || id.trim().isEmpty()) {
                return buildParamErrorResult(paramName + "中包含无效的ID");
            }
        }
        return Result.success();
    }

    /**
     * 记录操作日志
     * 
     * @param operation 操作名称
     * @param params 参数
     */
    protected void logOperation(String operation, Object... params) {
        log.info("执行{}操作，参数：{}", operation, params);
    }

    /**
     * 记录操作成功日志
     * 
     * @param operation 操作名称
     * @param result 结果
     */
    protected void logOperationSuccess(String operation, Object result) {
        log.info("{}操作成功，结果：{}", operation, result);
    }

    /**
     * 记录操作失败日志
     * 
     * @param operation 操作名称
     * @param error 错误信息
     */
    protected void logOperationFailure(String operation, String error) {
        log.error("{}操作失败：{}", operation, error);
    }
}
